/*
 * @Author: zoubotao
 * @Date: 2020-12-09 09:50:31
 * @LastEditors: zengy
 * @LastEditTime: 2021-07-27 19:20:53
 * @FilePath: \Mics3.0_3DViewer_WEB\3DViewer\src\plugins\socket.js
 */
import CONFIG from '@/config';
import store from '@/store';

class WS {
  url = `${CONFIG.WS_URL}`;
  socket = null;
  reconnectState = false;
  timeout = CONFIG.TIMEOUT || 10000;
  heartTimer = null;
  noHeartTimer = null;
  reConnectTime = null;
  callback = null;
  constructor(params = [], callback = () => {},opencb=()=>{}, isHeart = true) {
    this.params = params;
    this.callback = callback;
    this.isHeart = isHeart;
    this.opencb = opencb;
    this.initWs();
  }
  //重置心跳
  reset() {
    clearTimeout(this.heartTimer);
    clearTimeout(this.noHeartTimer);
    this.isHeart && this.start();
  }
  //心跳持久化
  start() {
    this.heartTimer = setTimeout(() => {
      this.socket.readyState == 1 &&
        this.socket.send(
          JSON.stringify({
            command: 'HEATBEAT',
          })
        );
      console.log(
        `检测：%c 心跳连接是否正常...`,
        'font-size:12px;color:blue;font-weight:900'
      );
      this.noHeartTimer = setTimeout(() => {
        console.warn('心跳无响应，正在初始化重连中......');
        this.socket.close();
      }, this.timeout);
    }, this.timeout);
  }
  //websocket初始化发送的数据
  onopen() {
    this.opencb();
    console.log(`初始化连接中，准备执行数据发送...`);
    console.log(`执行默认心跳包发送HEATBEAT...`);
    this.socket.send(
      JSON.stringify({
        command: 'HEATBEAT',
      })
    );
    if (this.params) {
      if (Array.isArray(this.params)) {
        this.params.forEach(val => {
          this.socket.send(JSON.stringify(val));
        });
      } else {
        this.socket.send(JSON.stringify(this.params));
      }
    }
    console.log('启动心跳逻辑...');
    this.reset();
  }
  //数据发送
  send(data) {
    let {command,params} = data;
    if(command === 'CLEAR'){
      this.params = this.params.filter(v=>{
        return !params.includes(v.command);
      })
    }else{
      this.params.push(data);
    }
    this.socket.send(JSON.stringify(data));
  }
  //数据接收
  onmessage(e) {
    this.handleEvent(e);
  }
  //异常回调
  onclose(e) {
    if (this.reconnectState) {
      return;
    }
    console.group('心跳连接异常....');
    console.error(`错误代码：${e.code}`);
    console.groupEnd();
    this.reConnect();
  }
  //初始化websocket
  initWs() {
    const self = this;
    window.WebSocket = window.WebSocket || window.MozWebSocket;
    if (!window.WebSocket) {
      console.error('错误: 浏览器不支持websocket');
      return;
    }
    this.reconnectState = false;
    this.socket = new WebSocket(
      `${this.url}${store.state.token ? `?token=${store.state.token}` : ''}`
    ); // 创建连接并注册响应函数
    this.socket.onopen = function(e) {
      self.onopen(e);
    };
    this.socket.onmessage = function(e) {
      self.onmessage(e);
    };
    this.socket.onclose = function(e) {
      self.onclose(e);
    };
    return this;
  }
  //重连
  reConnect() {
    if (this.reconnectState) return;
    console.log(`重连中,${CONFIG.RECONNECT_TIME / 1000}秒后执行重连逻辑...`);
    this.reconnectState = true;
    this.reConnectTime = setTimeout(() => {
      this.initWs();
    }, CONFIG.RECONNECT_TIME);
  }
  //强制关闭websocket
  closeWs(fn) {
    this.reconnectState = true;
    if (this.socket) this.socket.close();
    console.log(
      '%c websocket已被强制关闭',
      'font-size:12px;color:red;font-weight:900'
    );
    fn && fn();
    clearTimeout(this.reConnectTime);
    clearTimeout(this.heartTimer);
    clearTimeout(this.noHeartTimer);
  }
  //处理返回的数据
  handleEvent(message) {
    let data = JSON.parse(message.data);
    if (data.command === 'HEATBEAT') {
      this.reset();
    } else {
      if (this.callback) {
        this.callback(data);
      }
    }
  }
}

window.IMCWS = WS;
export default WS;
